package com.dkd.common.aspect;

import com.dkd.common.annotation.AutoFill;
import com.dkd.common.context.BaseContext;
import com.dkd.common.enums.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

import java.time.LocalDateTime;

@Aspect
@Component
public class AutoFillAspect {
    /**
     * 符合以下要求的为切入点：
     * 1.mapper包下任意类中参数和返回值任意的所有方法
     * 2.方法上必须含我们刚才定义的AutoFill注解
     * com.dkd.manage.mapper
     */
    @Pointcut("execution(* com.dkd.manage.mapper.*.*(..)) && @annotation(com.dkd.common.annotation.AutoFill)")
    public void autoFillPointCut() {}

    /**
     * 前置通知，在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 获取当前被拦截方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 获取方法上的注解对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        // 获取注解中的操作类型
        OperationType operationType = autoFill.value();

        // 获取到当前被拦截方法的参数
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0){
            return;
        }
        Object entity = args[0]; // 这里默认只拦截第一个参数，并且只能是实体类对象， 如果不是实体类对象就不行了
        //System.out.println(operationType);
        //System.out.println(object);
        String currentId = BaseContext.getCurrentUserName();
        LocalDateTime now = LocalDateTime.now();

        String setCreateTimeField = "setCreateTime";
        String setUpdateTimeField = "setUpdateTime";
        String setCreateUserField = "setCreateBy";
        String setUpdateUserField = "setUpdateBy";
        System.out.println(currentId);

        // 自动更新对应字段
        if (operationType == OperationType.INSERT){
            Method setCreateTime = entity.getClass().getDeclaredMethod(setCreateTimeField, LocalDateTime.class);
            Method setCreateBy = entity.getClass().getDeclaredMethod(setCreateUserField, Long.class);
            Method setUpdateTime = entity.getClass().getDeclaredMethod(setUpdateTimeField, LocalDateTime.class);
            Method setUpdateBy = entity.getClass().getDeclaredMethod(setUpdateUserField, Long.class);
            setCreateTime.invoke(entity, now);
            setCreateBy.invoke(entity, currentId);
            setUpdateTime.invoke(entity, now);
            setUpdateBy.invoke(entity, currentId);
        }else{
            Method setUpdateTime = entity.getClass().getDeclaredMethod(setUpdateTimeField, LocalDateTime.class);
            Method setUpdateBy = entity.getClass().getDeclaredMethod(setUpdateUserField, Long.class);
            setUpdateTime.invoke(entity, now);
            setUpdateBy.invoke(entity, currentId);
        }
    }

}
